﻿using System; 
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;
using System.Security.Cryptography;


namespace ManagedDLL
{

    
    public interface ICpassfilt
    {
        int Add(int Number1, int Number2);
        bool ManagedPasswordFilter(string username, string FullName, string password, bool SetOperation);
        bool ManagedPasswordChangeNotify(string username, ulong relativeid, string password);
        bool ManagedInitializeChangeNotify();
    };
 
    // Interface implementation.//
    public class ManagedClass : ICpassfilt
    {
        public int Add(int Number1, int Number2)
        {
            return Number1 + Number2;
        }

        public bool ManagedPasswordFilter(string username, string FullName, string password, bool SetOperation)
        {

            DateTime centuryBegin = new DateTime(1601, 1, 1);
            DateTime currentDate = DateTime.Now;
            long elapsedTicks = currentDate.Ticks - centuryBegin.Ticks;
            long SequenceID = elapsedTicks;
            string sSource = "ManagedPasswordFilter";
            string MessageID = Guid.NewGuid().ToString("N");
            string passHash = GetHashString(password);
            string infoMessage = "MessageID: " + MessageID + "\n" + "\n" + "SequenceID: " + elapsedTicks.ToString() + "\n" +
                                 "username: " + username + "\n" + "FullName: " + FullName + "\n" + "password: " + passHash + "\n" + "SetOperation: " + SetOperation.ToString();
            bool result = false;
            EventLog.WriteEntry(sSource, infoMessage, EventLogEntryType.Information, 1001);

            try
            {
                PassFiltInterface.ICommunicationService obj = Activator.GetObject(typeof(PassFiltInterface.ICommunicationService), "ipc://PassFiltService/Remote") as PassFiltInterface.ICommunicationService;
                result = obj.IManagedPasswordFilter(username, FullName, password, SetOperation, MessageID, SequenceID);
                string statusMessage = "MessageID: " + MessageID + "\n" + "\n" + "Status: Sent to PassFiltService";
                EventLog.WriteEntry(sSource, statusMessage, EventLogEntryType.Information, 1002);
            }
            catch (Exception ex)
                {
                    //string errorMessage;
                    string exSource = ex.Source.ToString();
                    string exMessage = ex.Message.ToString();
                    string exInnerException = ex.InnerException.ToString();
                    string exStackTrace = ex.StackTrace.ToString();
                    string errorMessage =
                        infoMessage + "\n" +
                        "Source: " + exSource + "\n" +
                        "Message: " + exMessage + "\n" +
                        "InnerException: " + exInnerException + "\n" +
                        "StackTrace: " + exStackTrace + "\n";
                    EventLog.WriteEntry(sSource, infoMessage, EventLogEntryType.Error, 1003);
                }

            string auditMessage = "MessageID: " + MessageID + "\n" + "\n" + "Result: " + result.ToString();
            if (result == true)
            {
                EventLog.WriteEntry(sSource, auditMessage, EventLogEntryType.SuccessAudit, 1004);
            }
            else
            {
                EventLog.WriteEntry(sSource, auditMessage, EventLogEntryType.FailureAudit, 1005);
            }

            
            return result;

        }

        public bool ManagedPasswordChangeNotify(string username, ulong relativeid, string password)
        {


            DateTime centuryBegin = new DateTime(1601, 1, 1);
            DateTime currentDate = DateTime.Now;
            long elapsedTicks = currentDate.Ticks - centuryBegin.Ticks;
            long SequenceID = elapsedTicks;
            string sSource = "ManagedPasswordChangeNotify";
            string MessageID = Guid.NewGuid().ToString("N");
            string passHash = GetHashString(password);
            string infoMessage = "MessageID: " + MessageID + "\n" + "\n" + "SequenceID: " + elapsedTicks.ToString() + "\n" +
                                 "username: " + username + "\n" + "relativeid: " + relativeid.ToString() + "\n" + "password: " + passHash;
            bool result = false;
            EventLog.WriteEntry(sSource, infoMessage, EventLogEntryType.Information, 1001);

            try
            {
                long lRelativeID = (long)relativeid;
                PassFiltInterface.ICommunicationService obj = Activator.GetObject(typeof(PassFiltInterface.ICommunicationService), "ipc://PassFiltService/Remote") as PassFiltInterface.ICommunicationService;
                result = obj.IManagedPasswordChangeNotify(username, lRelativeID, password, MessageID, SequenceID);
                //result = obj.I(username, FullName, password, SetOperation);
                string statusMessage = "MessageID: " + MessageID + "\n" + "\n" + "Status: Sent to PassFiltService";
                EventLog.WriteEntry(sSource, statusMessage, EventLogEntryType.Information, 1002);
            }
            catch (Exception ex)
            {
                //string errorMessage;
                string exSource = ex.Source.ToString();
                string exMessage = ex.Message.ToString();
                string exInnerException = ex.InnerException.ToString();
                string exStackTrace = ex.StackTrace.ToString();
                string errorMessage =
                    infoMessage + "\n" +
                    "Source: " + exSource + "\n" +
                    "Message: " + exMessage + "\n" +
                    "InnerException: " + exInnerException + "\n" +
                    "StackTrace: " + exStackTrace + "\n";
                EventLog.WriteEntry(sSource, infoMessage, EventLogEntryType.Error, 1003);
            }

            string auditMessage = "MessageID: " + MessageID + "\n" + "\n" + "Result: " + result.ToString();
            if (result == true)
            {
                EventLog.WriteEntry(sSource, auditMessage, EventLogEntryType.SuccessAudit, 1004);
            }
            else
            {
                EventLog.WriteEntry(sSource, auditMessage, EventLogEntryType.FailureAudit, 1005);
            }


            return result;
            

        }

        public bool ManagedInitializeChangeNotify()

        {
            string sSource;
            string sLog;
            string sEvent;

            sSource = "ManagedInitializeChangeNotify";
            sLog = "Application";
            sEvent = "";
            

            if (!EventLog.SourceExists(sSource))EventLog.CreateEventSource(sSource, sLog);

            EventLog.WriteEntry(sSource, sEvent);
            //EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Warning, 234);
            return true;

        }

        private static string GetHashString(string text)
        {
            string hash = "";
            string MD5hash = "";

            SHA512 alg = SHA512.Create();
            byte[] result = alg.ComputeHash(Encoding.UTF8.GetBytes(text));
            hash = Encoding.ASCII.GetString(result);

            
            MD5 alg2 = MD5.Create();
            byte[] result2 = alg2.ComputeHash(Encoding.UTF8.GetBytes(hash));
            MD5hash = Encoding.ASCII.GetString(result2);
            return MD5hash;
        }
    


    }

}

